#if DEBUG_VERSION
if (!dafos) {
  throw new Error("Dafos namespace not found!");
}
#if OPENSOCIAL_0_8
if (dafos.OpenSocial) {
  throw new Error("dafos.OpenSocial is already defined!");
}
#endif
#endif

#if OPENSOCIAL_0_8
dafos.OpenSocial = function() {
  this.version = "0.8";
  this.viewer = {};
  this.owner = {};
  this.peopledata = {};
};


/**
 * Gets the requested data key or a default value if there was an
 * error or no value
 */
dafos.OpenSocial.prototype.getDataOr = function(data, key, defaultvalue) {
  LOG("getDataOr, this=", this, "data=", data)
  return (data && 
          data.get(key) && 
          !data.get(key).hadError() &&
          data.get(key).getData()) || defaultvalue;
};

/**
 * Request the OpenSocial data needed for this app
 */
dafos.OpenSocial.prototype.getOpenSocialData = function(datakeys, callback) {
  LOG("getOpenSocialData: this = ", this);
  var req = opensocial.newDataRequest();

  //Request the owner's data
  req.add(
    req.newFetchPersonAppDataRequest(
      opensocial.newIdSpec({ "userId" : 'OWNER'}), datakeys),
    "peopledata");

  //Request the owner
  req.add(req.newFetchPersonRequest('OWNER'), "owner");
  
  //Request the viewer
  req.add(req.newFetchPersonRequest('VIEWER'), "viewer");
  
  //Send the request
  req.send(dafos.bind(this.closeGetOpenSocialData(callback), this));    
};

/**
 * Parse the data returned by the OpenSocial requests
 */
dafos.OpenSocial.prototype.closeGetOpenSocialData = function(callback) {
  LOG("closeGetOpenSocialData: this = ", this);
  return function(data) {
    LOG("getOpenSocialData: this = ", this);
    var tempdata = null,
        personkey = null,
        datakey = null;
  
    this.viewer = this.getDataOr(data, "viewer", this.viewer);
    this.owner = this.getDataOr(data, "owner", this.owner);
    tempdata = this.getDataOr(data, "peopledata", {});
  
    //Collapse the appData with the data we've already gotten
    this.mergePersonAppData.apply(this, [tempdata]);
    
    //Call the callback if appropriate
    if (callback && typeof(callback) == "function") {
      callback();
    }
  };
};

/**
 * Adds (and overwrites) the data store with a new data response
 */
dafos.OpenSocial.prototype.mergePersonAppData = function(newdata) {
  //Iterate over the person id keys in the data structure
  for (personkey in newdata) {
    if (newdata.hasOwnProperty(personkey)) {
      //If there's no index by this person's ID, create it
      this.peopledata[personkey] = this.peopledata[personkey] || {};
      
      //Iterate over the data key name in the data structure
      for (datakey in newdata[personkey]) {
        if (newdata[personkey].hasOwnProperty(datakey)) {
          this.peopledata[personkey][datakey] = 
            newdata[personkey][datakey];
        }
      }
    }
  }
};

/**
 * Returns true if the viewer is the same person as the owner
 */
dafos.OpenSocial.prototype.viewerIsOwner = function() {
  LOG("[viewerIsOwner]");
  var viewerId = this.viewer.getId && this.viewer.getId() || -1;
  var ownerId = this.owner.getId && this.owner.getId() || -2;
  
  LOG("  viewerId:", viewerId);
  LOG("  ownerId :", ownerId);
  return viewerId == ownerId;
};

/**
 * Sets the viewer's app data 
 */
dafos.OpenSocial.prototype.setAppData = function(data, key, callback) {
  var req = opensocial.newDataRequest();
  data = gadgets.json.stringify(data);
  
  req.add(
    req.newUpdatePersonAppDataRequest('VIEWER', key, data), "updatedata");
  req.add(
    req.newFetchPersonAppDataRequest(
      opensocial.newIdSpec({ "userId" : 'OWNER'}), key, data),
    "peopledata");
  req.send(dafos.bind(this.closeSetAppData(callback), this));
};

/**
 * Parse the app data returned by the set call
 */
dafos.OpenSocial.prototype.closeSetAppData = function(callback) {
  return function(data) {
    var tempdata = null,
        key = null;
  
    tempdata = this.getDataOr(data, "peopledata", {});

    //Collapse the appData with the data we've already gotten
    this.mergePersonAppData.apply(this, [tempdata]);

    //Call the callback if appropriate
    if (callback && typeof(callback) == "function") {
      callback();
    }
  };
};

dafos.OpenSocial.prototype.getPersonData = function(id) {
  return (id && this.peopledata[id]) || {};
};

dafos.OpenSocial.prototype.getViewerData = function() {
  return (this.viewer && 
          this.viewer.getId && 
          this.peopledata[this.viewer.getId()]) || {};
};

dafos.OpenSocial.prototype.getOwnerData = function() {
  return (this.owner && 
          this.owner.getId && 
          this.peopledata[this.owner.getId()]) || {};
};
#endif
